package database

import (
	"card/config"
	"card/pkg/logger"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"sync"
	"time"
)

type DbComponent = gorm.DB

var (
	daoOnce  sync.Once
	database = make(map[string]*DbComponent)
)

func Connection(dbConfig map[string]config.DataBaseConfig) {
	for k, v := range dbConfig {
		dao, err := gorm.Open(mysql.New(mysql.Config{
			DSN: getDsn(v),
		}), &gorm.Config{
			Logger: logger.NewGormLogger(),
		})
		if err != nil {
			panic(fmt.Errorf("数据库%s初始化失败，错误原因：%v", k, err))
		}
		sqlDB, err := dao.DB()
		if err != nil {
			panic(fmt.Errorf("获取数据库对象失败,数据库是%s,错误是%v", k, err))
		}
		// 设置最大连接数
		sqlDB.SetMaxOpenConns(v.MaxOpenConnections)
		// 设置最大空闲连接数
		sqlDB.SetMaxIdleConns(v.MaxIdleConnections)
		// 设置每个链接的过期时间
		sqlDB.SetConnMaxLifetime(time.Duration(v.MaxLifeSeconds) * time.Second)
		if err = sqlDB.Ping(); err != nil {
			panic(fmt.Errorf("数据库异常%v", err))
		}
		database[k] = dao
	}
}

func getDsn(db config.DataBaseConfig) string {
	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&multiStatements=true&loc=%s",
		db.Username,
		db.Password,
		db.Host,
		db.Database,
		db.Charset,
		db.ParseTime,
		db.Local,
	)
	return dsn
}

func GetDb(name string) *DbComponent {
	return database[name]
}
